Release 10.1A: OpenEdge Development:
Progress Dynamics Basic Development
Defining business logic for SBOs
The standard validation hooks for the SBO are basically the same as for the SDO: they have the names
preTransactionValidate,beginTransactionValidate,endTransactionValidate, andpostTransactionValidate. ThepreTransactionValidateprocedure executes before the corresponding procedure in any contained SDO and can modify values in SDO records that will be seen by the validation logic in the SDOs. ThebeginTransactionValidateprocedure executes at the very beginning of the single database transaction that encompasses all the updates in the SBO and its SDOs. Likewise, theendTransactionValidateprocedure executes at the very end.The dynamics SBO also supports a custom logic procedure that works just like the dynamic SDO’s custom logic procedure.
This first code example verifies that the client-side logic defined for an SDO will execute even when it is contained in an SBO. The Object Generator creates code for you in each SDO that verifies that all indexed fields have been entered. Because this code can be executed without returning to the server where the database is, it is placed into the client-side
rowObjectValidateprocedure, as shown:
If you run the
ordersbowinwindow, delete theSalesRepcode from anOrder, then choose Save, you immediately see the Progress Dynamics message shown in Figure 11–10.Figure 11–10: ADM2 message
![]()
Because the logic executes on the client, you see the error as soon as you choose Save, without having to do a commit.
The next code example shows that the SDO’s
preTransactionValidateorwritePreTransValidatelogic will be executed from inside an SBO. The following excerpt from thewritePreTransValidateprocedure generated for theOrderSDO by the Object Builder verifies that an updatedOrderNumfield does not match an existingOrderNumin the database:
For example, if you run the SBO window and change
OrderNumfrom 1 to 2, then choose Save, and then Commit, the error message shown in Figure 11–11 appears.Figure 11–11: ADM2 error message
![]()
Because this logic must execute on the server side, you do not see the error when you first choose Save. At that time, the change is saved only locally on the client. Only when you choose Commit to send the change back to the server does the
writePreTransValidateexecute. The code formats the error message and returns it up the execution stack, where it is intercepted by the framework code and returned to the client for display.The next code example shows the interaction between the SBO
preTransactionValidateand its counterpart in the SDO. In this rather contrived bit of code, the procedure first checks that if the PO field is not blank, then it must begin with the lettersPO. If not, the code returns an error. Otherwise, if it is blank, it is replaced by the string<none>. In the SBO, each contained SDO’s temp-table has, by default, the unqualified name of the SDO itself. You can change this value in the Instance Property dialog box for the SDOs within the SBO, as shown in the following example:
If you run the application again with this code, then save and commit any change to an
Orderrecord with a blank PO, the value is changed to<none>. This value is returned to the client and displayed after the change is committed.The next code sample adds another check to the
OrderSDO’swritePreTransValidateprocedure. As described in Chapter 10, "Building Basic Business Logic in a Progress Dynamics Application," if you use thecreate/write/deletevalidation procedures in the SDO logic procedure, the buffer name is the simple table name preceded byb_, as shown:
This code verifies that the PO number field has not been set to the string
<none>. If it has, then an error is reported. This example does not put this error into the Progress Dynamics message table as recommended you always do. For this reason, the message text is just inserted into the message formatting include fileaferrortxt.i.Because the SBO’s
preTransactionValidateprocedure executes first, it changes a blank PO number to‘<none>’, and passes this along to the SDO for further validation. Thus a blank PO is rejected with the error message that it cannot equal<none>!The next block of code shows how the SBO can look at updates in more than one SDO, referring to each by its logical name. This logic totals the quantity of any modified
OrderLinerecords of eachOrderrecord, which was itself modified. It puts that total into theOrderrecord’s PO field, so that the calculation can be seen back on the client when the transaction completes, as shown:
The next example is a
beginTransactionValidateprocedure for the SBO. This is the place to put logic that must lock or modify other database records before the SDOs’ updates are written back to the database. This simple example identifies eachOrderLinewhere the Price field has been modified, finds the correspondingItemrecord in the database, and modifies that record’s Price field to match. (This almost certainly is not what real-world business logic would want to do, but it serves the purpose of a demonstration.) TheItemrecord is updated as part of the same transaction as theOrderLinechanges, as shown:
Notes: As an alternative to defining a second buffer for the Before version of a changed record, as the previous example did, if you only need to know which fields were modified, you can look at the
ChangedFieldsfield of the update table record. If the condition is true (theOrderand the Price orQtyof at least one of itsOrderLinerecords have been changed), then all theOrderLinerecords for theOrderare re-read from the database, totaled, and the total placed into the PO field of theOrder.
This kind of logic has to take place at the end of the transaction, because both modifiedOrderLinerecords and unmodifiedOrderLinerecords must be read. You want the total to reflect both updates that were just made within the transaction, and any otherOrderLinerecords that were also in the database but not modified in this transaction.Finally, you define an
endTransactionValidateprocedure for the SBO. This is the place to put logic that must execute within the transaction block, but after all of the SDO updates have taken place. The procedure determines if anOrderrecord has been changed, and if the Qty or Price field for at least one of itsOrderLinerecords has also changed.In addition, because it is actually the ExtendedPrice that is being totaled, and the ExtendedPrice is calculated by a database trigger, this value will be available only at the end of the transaction, after the individual
OrderLinerecords have been written to the database.To demonstrate returning an error from within the transaction, the following code example then checks the
CreditLimitof theCustomerrecord associated with the updatedOrder. It returns an error message if theCreditLimithas been exceeded by this newOrdertotal. If this happens, the whole transaction is backed out, the error message will be returned to the client, and the user will be able to make whatever changes are necessary to be able to resubmit the updates successfully. Or the user can back out of all the changes to all SDOs by choosing the Undo button, as shown:
After making some changes to the database with this logic, the
Orderrecords will start to look rather strange. The values in angle brackets (< >) are the totals ofOrderLinequantities modified within a transaction. The values in square brackets ([ ]) are theOrdertotals, that is, the total of all ExtendedPrice values for allOrderLinerecords for anOrder, whenever both theOrderrecord and the Qty or Price fields of one or more of theOrderLinerecords have been modified within a single transaction.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |